package com.bckj.fastboot.core.extra.stage;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class StageInterfaceAnalyzer {

    /**
     * 获取对象实现的所有 Stage 相关接口（包括 Stage 及其子接口）
     * @param stage Stage 对象实例
     * @return 所有 Stage 相关接口的集合（去重）
     */
    public static Set<Class<?>> getAllStageInterfaces(Stage<? extends BaseStageContext> stage) {
        // 获取对象的 Class 实例
        Class<?> stageClass = stage.getClass();

        // 收集所有接口（直接 + 父接口）
        Set<Class<?>> allInterfaces = new HashSet<>();
        collectAllInterfaces(stageClass, allInterfaces);

        // 过滤出 Stage 体系接口（包括 Stage 及其子接口）
        return allInterfaces.stream()
                .filter(StageInterfaceAnalyzer::isStageInterface)
                .collect(Collectors.toSet());
    }

    /**
     * 递归收集类的所有接口（直接接口 + 父接口）
     * @param clazz 当前类
     * @param collector 接口收集器
     */
    private static void collectAllInterfaces(Class<?> clazz, Set<Class<?>> collector) {
        // 获取当前类直接实现的接口
        Class<?>[] directInterfaces = clazz.getInterfaces();
        for (Class<?> iface : directInterfaces) {
            if (!collector.contains(iface)) {
                collector.add(iface);
                // 递归收集父接口
                collectAllInterfaces(iface, collector);
            }
        }

        // 获取父类并递归收集其接口（可选，根据需求决定是否包含父类接口）
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null && !superClass.equals(Object.class)) {
            collectAllInterfaces(superClass, collector);
        }
    }

    /**
     * 判断一个类是否是 Stage 体系接口（包括 Stage 及其子接口）
     * @param clazz 待判断的类
     * @return true=是 Stage 体系接口
     */
    private static boolean isStageInterface(Class<?> clazz) {
        // 检查是否直接是 Stage 接口
        if (clazz.equals(Stage.class)) {
            return true;
        }

        // 检查是否是 Stage 的子接口（通过泛型原始类型判断）
        Type[] genericInterfaces = clazz.getGenericInterfaces();
        for (Type genericIt : genericInterfaces) {
            if (genericIt instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) genericIt;
                Type rawType = pt.getRawType();
                if (rawType.equals(Stage.class)) {
                    return true;
                }
            }
        }

        // 递归检查父接口
        Class<?>[] superInterfaces = clazz.getInterfaces();
        for (Class<?> superIface : superInterfaces) {
            if (isStageInterface(superIface)) {
                return true;
            }
        }

        return false;
    }
}
